package com.lsj.core.util;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.lsj.core.page.QueryTag;
import com.lsj.core.page.QueryEnum;
import com.lsj.core.exception.CustomerException;
import com.lsj.core.response.ResponseType;
import org.apache.commons.lang3.ObjectUtils;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author:lin.sj
 * @Data:2021/7/7 20:32
 * @Desc:
 */
public class QueryHelperUtil {

    /**
     * @Author: lin.sj
     * @Date: 2021/7/7 20:47
     * @Desc:
     * 1.封装转换简单的查询语句信息(and条件)，不能处理isNull条件，因为语句的组装本来就要判断是否包含值，这个只能自己另外处理
     * 2.使用条件，要求entity与dto的名称一致
     **/
    public static  <T> QueryWrapper<T> getSimpleWhere(Class<T> tClass,Object queryObj,String... ignoreArray){
        QueryWrapper<T> w = new QueryWrapper<>();
        if(queryObj == null){
            return w;
        }
        try{
            //获取忽略的字段set
            Set<String> ignoreSet = new HashSet<>();
            if(ignoreArray != null){
                ignoreSet.addAll(Arrays.asList());
            }
            //拼接语句
            Field[] fields = queryObj.getClass().getDeclaredFields();
            for(Field field:fields){
                field.setAccessible(true);
                Object value = field.get(queryObj);
                QueryTag queryTag = field.getAnnotation(QueryTag.class);
                //获取entity真实的字段名
                String fieldName = getRealFieldName(queryTag, field);
                String dbFieldName = getDbFieldName(tClass,fieldName);
                //获取匹配关键字
                String keyWord = getKeyWord(queryTag);
                //判断该字段是否为忽略字段且内容是否为空
                if (!ignoreSet.contains(fieldName) && valueNotNull(value)){
                    if(QueryEnum.eq.name().equals(keyWord)){
                        w.eq(dbFieldName,value);
                    }else if(QueryEnum.like.name().equals(keyWord)){
                        w.like(dbFieldName,value);
                    }else if(QueryEnum.notLike.name().equals(keyWord)){
                        w.notLike(dbFieldName,value);
                    }else if(QueryEnum.in.name().equals(keyWord)){
                        w.in(dbFieldName,value);
                    }else if(QueryEnum.notIn.name().equals(keyWord)){
                        w.notIn(dbFieldName,value);
                    }else if(QueryEnum.isNotNull.name().equals(keyWord)){
                        w.isNotNull(dbFieldName);
                    }
                }
            }
        }catch (Exception e){
            throw new CustomerException(ResponseType.system_error,"查询参数转换出错！");
        }
        return w;
    }

    private static <T> String getDbFieldName(Class<T> tClass, String fieldName)  throws Exception{
        Field field = tClass.getDeclaredField(fieldName);
        TableField annotation = field.getAnnotation(TableField.class);
        if(annotation == null){
            TableId IdAnnotation = field.getAnnotation(TableId.class);
            return IdAnnotation.value();
        }
        return annotation.value();
    }

    /**
     * @Author: lin.sj
     * @Date: 2021/7/12 21:15
     * @Desc: 从dto字符段中，获取entity中对应的真实字段名称：如果QueryTag为空||queryTag.fieldName为空，
     *        取dto字段名称，否则取queryTag.fieldName
     **/
    private static String getRealFieldName(QueryTag queryTag,Field field){
        if (queryTag == null || StringUtils.isBlank(queryTag.fieldName())){
            return field.getName();
        }else{
            return queryTag.fieldName();
        }
    }
    
    /*从queryTag中获取匹配关键字，没有queryTag就是eq*/
    private static String getKeyWord(QueryTag queryTag){
        if(queryTag == null){
            return QueryEnum.eq.name();
        }else{
            return queryTag.value().name();
        }
    }

    public static <T> LambdaQueryWrapper<T> getLambdaWrapper(Class<T> tClass){
        return new LambdaQueryWrapper<T>();
    }
    public static <T> QueryWrapper<T> getWrapper(Class<T> tClass){
        return new QueryWrapper<T>();
    }

    //判断参入对象是否为空或空字符串
    private static boolean valueNotNull(Object obj){
        if(ObjectUtils.isNotEmpty(obj) && !(obj instanceof StringUtils)){
            return true;
        }
        if(obj instanceof StringUtils && StringUtils.isNotBlank(Convert.toStr(obj))){
            return true;
        }
        return false;
    }


}
